home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / read.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  15KB  |  698 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : August 1985.
  7.  *    2nd revision : March 1988.
  8.  *
  9.  *    %W%    %G%
  10. */
  11. #include "fig.h"
  12. #include "alloc.h"
  13. #include "object.h"
  14.  
  15. extern F_arrow        *make_arrow();
  16.  
  17. static F_ellipse    *read_ellipseobject();
  18. static F_line        *read_lineobject();
  19. static F_text        *read_textobject();
  20. static F_spline        *read_splineobject();
  21. static F_arc        *read_arcobject();
  22. static F_compound    *read_compoundobject();
  23.  
  24. #define            BUF_SIZE        1024
  25.  
  26. char            buf[BUF_SIZE];
  27. int            line_no = 0;
  28. int            num_object;
  29.  
  30. read_fail_message(file, err)
  31. char    *file;
  32. int    err;
  33. {
  34.     extern char    *sys_errlist[];
  35.  
  36.     if (err == 0)        /* Successful read */
  37.         return;
  38.     /*
  39.     else if (err == ENAMETOOLONG)
  40.         put_msg("File name \"%s\" is too long", file);
  41.     */
  42.     else if (err == ENOENT)
  43.         put_msg("File \"%s\" does not exist", file);
  44.     /*
  45.     else if (err == ENOTDIR)
  46.         put_msg("A name in the path \"%s\" is not a directory", file);
  47.     */
  48.     else if (err == EACCES)
  49.         put_msg("Read access to file \"%s\" is blocked", file);
  50.     /*
  51.     else if (err == EISDIR)
  52.         put_msg("File \"%s\" is a directory", file);
  53.     */
  54.     else if (err == -2) {
  55.         put_msg("File \"%s\" is empty", file);
  56.         }
  57.     else if (err == -1) {
  58.         /* Format error; relevant error message is already delivered */
  59.         }
  60.     else
  61.         put_msg("File \"%s\" is not accessable; %s", file, sys_errlist[err]);
  62.     }
  63.  
  64. /**********************************************************
  65. Read_fig returns :
  66.  
  67.      0 : successful read.
  68.     -1 : File is in incorrect format
  69.     -2 : File is empty
  70. err_no : if file can not be read for various reasons
  71.  
  72. The resolution (ppi) and the cooridnate system (coord_sys) are
  73. stored in obj->nwcorner.x and obj->nwcorner.x respectively.
  74. **********************************************************/
  75.  
  76. read_fig(file_name, obj)
  77. char        *file_name;
  78. F_compound    *obj;
  79. {
  80.     FILE    *fp;
  81.  
  82.     if ((fp = fopen(file_name, "r")) == NULL)
  83.         return(errno);
  84.     else
  85.         return(readfp_fig(fp, obj));
  86.     }
  87.  
  88. readfp_fig(fp, obj)
  89. FILE  *fp;
  90. F_compound    *obj;
  91. {
  92.         char            c;
  93.         int             status;
  94.   
  95.     num_object = 0;
  96.     c = fgetc(fp);
  97.     if (feof(fp)) return(-2);
  98.     ungetc(c, fp);
  99.     bzero((char*)obj, COMOBJ_SIZE);
  100.     if (c == '#')
  101.         status = read_objects(fp, obj);
  102.     else
  103.         status = read_1_3_objects(fp, obj);
  104.  
  105.     fclose(fp);
  106.     return(status);
  107.         }
  108.     
  109. int
  110. read_objects(fp, obj)
  111. FILE        *fp;
  112. F_compound    *obj;
  113. {
  114.     F_ellipse    *e, *le = NULL;
  115.     F_line        *l, *ll = NULL;
  116.     F_text        *t, *lt = NULL;
  117.     F_spline    *s, *ls = NULL;
  118.     F_arc        *a, *la = NULL;
  119.     F_compound    *c, *lc = NULL;
  120.     int        object, ppi, coord_sys;
  121.  
  122.     fgets(buf, BUF_SIZE, fp);    /* get the line "#FIG 1.4" */
  123.     line_no++;
  124.     if (get_line(fp) < 0) {
  125.         put_msg("File is truncated");
  126.         return(-1);
  127.         }
  128.     if (2 != sscanf(buf,"%d %d\n", &ppi, &coord_sys)) {
  129.         put_msg("Incomplete data at line %d", line_no);
  130.         return(-1);
  131.         }
  132.  
  133.     obj->nwcorner.x = ppi;
  134.     obj->nwcorner.y = coord_sys;
  135.     while (get_line(fp) > 0) {
  136.         if (1 != sscanf(buf, "%d", &object)) {
  137.         put_msg("Incorrect format at line %d", line_no);
  138.         return(-1);
  139.         }
  140.  
  141.         switch (object) {
  142.         case O_POLYLINE :
  143.             if ((l = read_lineobject(fp)) == NULL) return(-1);
  144.             if (ll)
  145.             ll = (ll->next = l);
  146.             else 
  147.             ll = obj->lines = l;
  148.             num_object++;
  149.             break;
  150.         case O_SPLINE :
  151.             if ((s = read_splineobject(fp)) == NULL) return(-1);
  152.             if (ls)
  153.             ls = (ls->next = s);
  154.             else 
  155.             ls = obj->splines = s;
  156.             num_object++;
  157.             break;
  158.         case O_ELLIPSE :
  159.             if ((e = read_ellipseobject()) == NULL) return(-1);
  160.             if (le)
  161.             le = (le->next = e);
  162.             else 
  163.             le = obj->ellipses = e;
  164.             num_object++;
  165.             break;
  166.         case O_ARC :
  167.             if ((a = read_arcobject(fp)) == NULL) return(-1);
  168.             if (la)
  169.             la = (la->next = a);
  170.             else 
  171.             la = obj->arcs = a;
  172.             num_object++;
  173.             break;
  174.         case O_TEXT :
  175.             if ((t = read_textobject()) == NULL) return(-1);
  176.             if (lt)
  177.             lt = (lt->next = t);
  178.             else 
  179.             lt = obj->texts = t;
  180.             num_object++;
  181.             break;
  182.         case O_COMPOUND :
  183.             if ((c = read_compoundobject(fp)) == NULL) return(-1);
  184.             if (lc)
  185.             lc = (lc->next = c);
  186.             else 
  187.             lc = obj->compounds = c;
  188.             num_object++;
  189.             break;
  190.         default :
  191.             put_msg("Incorrect object code at line %d", line_no);
  192.             return(-1);
  193.         } /*  switch */
  194.         } /*  while */
  195.     if (feof(fp))
  196.         return(0);
  197.     else
  198.         return(errno);
  199.     } /*  read_objects */
  200.  
  201. static F_arc *
  202. read_arcobject(fp)
  203. FILE    *fp;
  204. {
  205.     F_arc    *a;
  206.     int    n, fa, ba;
  207.     int    type, style;
  208.     float    thickness, wid, ht;
  209.  
  210.     if (NULL == (Arc_malloc(a))) {
  211.         put_msg(Err_mem);
  212.         return(NULL);
  213.         }
  214.     a->pen = NULL;
  215.     a->area_fill = NULL;
  216.     a->next = NULL;
  217.     n = sscanf(buf, "%*d%d%d%d%d%d%*d%*d%f%d%d%d%f%f%d%d%d%d%d%d\n",
  218.         &a->type, &a->style, &a->thickness, 
  219.         &a->color, &a->depth, /* skip pen and area_fill */
  220.         &a->style_val, &a->direction, &fa, &ba,
  221.         &a->center.x, &a->center.y, 
  222.         &a->point[0].x, &a->point[0].y, 
  223.         &a->point[1].x, &a->point[1].y, 
  224.         &a->point[2].x, &a->point[2].y);
  225. /*    if (n != 17) {*/
  226.     if (n != 17 + 3) {
  227.         put_msg(Err_incomp, "arc", line_no);
  228.         free((char*)a);
  229.         return(NULL);
  230.         }
  231.  
  232.     skip_comment(fp);
  233.     if (fa) {
  234.         line_no++;
  235.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  236.         fprintf(stderr, Err_incomp, "arc", line_no);
  237.         return(NULL);
  238.         }
  239.         skip_line(fp);
  240.         a->for_arrow = make_arrow(type, style, thickness, wid, ht);
  241.         skip_comment(fp);
  242.         }
  243.     skip_comment(fp);
  244.     if (ba) {
  245.         line_no++;
  246.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  247.         fprintf(stderr, Err_incomp, "arc", line_no);
  248.         return(NULL);
  249.         }
  250.         skip_line(fp);
  251.         a->back_arrow = make_arrow(type, style, thickness, wid, ht);
  252.         }
  253.     return(a);
  254.     }
  255.  
  256. static F_compound *
  257. read_compoundobject(fp)
  258. FILE    *fp;
  259. {
  260.     F_arc        *a, *la = NULL;
  261.     F_ellipse    *e, *le = NULL;
  262.     F_line        *l, *ll = NULL;
  263.     F_spline    *s, *ls = NULL;
  264.     F_text        *t, *lt = NULL;
  265.     F_compound    *com, *c, *lc = NULL;
  266.     int        n, object;
  267.  
  268.     Compound_malloc(com);
  269.     com->arcs = NULL;
  270.     com->ellipses = NULL;
  271.     com->lines = NULL;
  272.     com->splines = NULL;
  273.     com->texts = NULL;
  274.     com->compounds = NULL;
  275.     com->next = NULL;
  276.     n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y,
  277.         &com->secorner.x, &com->secorner.y);
  278. /*    if (4 != n) {*/
  279.     if (4 + 1 != n) {
  280.         put_msg(Err_incomp, "compound", line_no);
  281.         free((char*)com);
  282.         return(NULL);
  283.         }
  284.     while (get_line(fp) > 0) {
  285.         if (1 != sscanf(buf, "%d", &object)) {
  286.         put_msg(Err_incomp, "compound", line_no);
  287.         free_compound(&com);
  288.         return(NULL);
  289.         }
  290.         switch (object) {
  291.         case O_POLYLINE :
  292.             if ((l = read_lineobject(fp)) == NULL) { 
  293.             free_line(&l);
  294.             return(NULL);
  295.             }
  296.             if (ll)
  297.             ll = (ll->next = l);
  298.             else 
  299.             ll = com->lines = l;
  300.             break;
  301.         case O_SPLINE :
  302.             if ((s = read_splineobject(fp)) == NULL) { 
  303.             free_spline(&s);
  304.             return(NULL);
  305.             }
  306.             if (ls)
  307.             ls = (ls->next = s);
  308.             else 
  309.             ls = com->splines = s;
  310.             break;
  311.         case O_ELLIPSE :
  312.             if ((e = read_ellipseobject()) == NULL) { 
  313.             free_ellipse(&e);
  314.             return(NULL);
  315.             }
  316.             if (le)
  317.             le = (le->next = e);
  318.             else 
  319.             le = com->ellipses = e;
  320.             break;
  321.         case O_ARC :
  322.             if ((a = read_arcobject(fp)) == NULL) { 
  323.             free_arc(&a);
  324.             return(NULL);
  325.             }
  326.             if (la)
  327.             la = (la->next = a);
  328.             else 
  329.             la = com->arcs = a;
  330.             break;
  331.         case O_TEXT :
  332.             if ((t = read_textobject()) == NULL) { 
  333.             free_text(&t);
  334.             return(NULL);
  335.             }
  336.             if (lt)
  337.             lt = (lt->next = t);
  338.             else 
  339.             lt = com->texts = t;
  340.             break;
  341.         case O_COMPOUND :
  342.             if ((c = read_compoundobject(fp)) == NULL) { 
  343.             free_compound(&c);
  344.             return(NULL);
  345.             }
  346.             if (lc)
  347.             lc = (lc->next = c);
  348.             else 
  349.             lc = com->compounds = c;
  350.             break;
  351.         case O_END_COMPOUND :
  352.             return(com);
  353.         default :
  354.             put_msg("Wrong object code at line %d", line_no);
  355.             return(NULL);
  356.         } /*  switch */
  357.         }
  358.     if (feof(fp))
  359.         return(com);
  360.     else
  361.         return(NULL);
  362.     }
  363.  
  364. static F_ellipse *
  365. read_ellipseobject()
  366. {
  367.     F_ellipse    *e;
  368.     int        n, pen, fill;
  369.  
  370.     Ellipse_malloc(e);
  371.     e->area_fill = NULL;
  372.     e->pen = NULL;
  373.     e->next = NULL;
  374.     n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%f%d%d%d%d%d%d%d%d\n",
  375.         &e->type, &e->style, &e->thickness,
  376.         &e->color, &e->depth, &pen, &fill,
  377.         &e->style_val, &e->direction, &e->angle,
  378.         &e->center.x, &e->center.y, 
  379.         &e->radiuses.x, &e->radiuses.y, 
  380.         &e->start.x, &e->start.y, 
  381.         &e->end.x, &e->end.y);
  382.  
  383. /*    if (n != 18) {*/
  384.     if (n != 18 + 1) {
  385.         put_msg(Err_incomp, "ellipse", line_no);
  386.         free((char*)e);
  387.         return(NULL);
  388.         }
  389.     return(e);
  390.     }
  391.  
  392. static F_line *
  393. read_lineobject(fp)
  394. FILE    *fp;
  395. {
  396.     F_line    *l;
  397.     F_point    *p, *q;
  398.     int    n, x, y, pen, fill, fa, ba;
  399.     int    type, style;
  400.     float    thickness, wid, ht;
  401.  
  402.     Line_malloc(l);
  403.     l->points = NULL;
  404.     l->pen = NULL;
  405.     l->area_fill = NULL;
  406.     l->for_arrow = NULL;
  407.     l->back_arrow = NULL;
  408.     l->next = NULL;
  409.  
  410.     n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%d",
  411.         &l->type, &l->style, &l->thickness, &l->color,
  412.         &l->depth, &pen, &fill, &l->style_val, &fa, &ba);
  413. /*    if (n != 10) {*/
  414.     if (n != 10 + 1) {
  415.         put_msg(Err_incomp, "line", line_no);
  416.         free((char*)l);
  417.         return(NULL);
  418.         }
  419.     skip_comment(fp);
  420.     if (fa) {
  421.         line_no++;
  422.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  423.         fprintf(stderr, Err_incomp, "line", line_no);
  424.         return(NULL);
  425.         }
  426.         skip_line(fp);
  427.         l->for_arrow = make_arrow(type, style, thickness, wid, ht);
  428.         skip_comment(fp);
  429.         }
  430.     if (ba) {
  431.         line_no++;
  432.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  433.         fprintf(stderr, Err_incomp, "line", line_no);
  434.         return(NULL);
  435.         }
  436.         skip_line(fp);
  437.         l->back_arrow = make_arrow(type, style, thickness, wid, ht);
  438.         skip_comment(fp);
  439.         }
  440.  
  441.     if (NULL == (l->points = Point_malloc(p))) {
  442.         put_msg(Err_mem);
  443.         return(NULL);
  444.         }
  445.     if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
  446.         put_msg(Err_incomp, "line", line_no);
  447.         free_linestorage(l);
  448.         return(NULL);
  449.         }
  450.     for (;;) {
  451.         if (fscanf(fp, "%d%d", &x, &y) != 2) {
  452.         put_msg(Err_incomp, "line", line_no);
  453.         free_linestorage(l);
  454.         return(NULL);
  455.         }
  456.         if (x == 9999) break;
  457.         if (NULL == (Point_malloc(q))) {
  458.         put_msg(Err_mem);
  459.         free_linestorage(l);
  460.         return(NULL);
  461.         }
  462.         q->x = x;
  463.         q->y = y;
  464.         q->next = NULL;
  465.         p->next = q;
  466.         p = q;
  467.         }
  468.     skip_line(fp);
  469.     return(l);
  470.     }
  471.  
  472. static F_spline *
  473. read_splineobject(fp)
  474. FILE    *fp;
  475. {
  476.     F_spline    *s;
  477.     F_point        *p, *q;
  478.     F_control    *cp, *cq;
  479.     int        c, n, x, y, pen, fill, fa, ba;
  480.     int        type, style;
  481.     float        thickness, wid, ht;
  482.     float        lx, ly, rx, ry;
  483.  
  484.     Spline_malloc(s);
  485.     s->points = NULL;
  486.     s->controls = NULL;
  487.     s->pen = NULL;
  488.     s->area_fill = NULL;
  489.     s->for_arrow = NULL;
  490.     s->back_arrow = NULL;
  491.     s->next = NULL;
  492.  
  493.     n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%d%d%d", 
  494.             &s->type, &s->style, &s->thickness, &s->color,
  495.         &s->depth, &pen, &fill, &s->style_val, &fa, &ba);
  496. /*    if (n != 10) {*/
  497.     if (n != 10 + 1) {
  498.         put_msg(Err_incomp, "spline", line_no);
  499.         free((char*)s);
  500.         return(NULL);
  501.         }
  502.     skip_comment(fp);
  503.     if (fa) {
  504.         line_no++;
  505.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  506.         fprintf(stderr, Err_incomp, "spline", line_no);
  507.         return(NULL);
  508.         }
  509.         skip_line(fp);
  510.         s->for_arrow = make_arrow(type, style, thickness, wid, ht);
  511.         skip_comment(fp);
  512.         }
  513.     if (ba) {
  514.         line_no++;
  515.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  516.         fprintf(stderr, Err_incomp, "spline", line_no);
  517.         return(NULL);
  518.         }
  519.         skip_line(fp);
  520.         s->back_arrow = make_arrow(type, style, thickness, wid, ht);
  521.         skip_comment(fp);
  522.         }
  523.  
  524.     /* Read points */
  525.     if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) {
  526.         put_msg(Err_incomp, "spline", line_no);
  527.         free_splinestorage(s);
  528.         return(NULL);
  529.         };
  530.     if (NULL == (s->points = Point_malloc(p))) {
  531.         put_msg(Err_mem);
  532.         free_splinestorage(s);
  533.         return(NULL);
  534.         }
  535.     p->x = x; p->y = y;
  536.     for (c = 1;;) {
  537.         if (fscanf(fp, "%d%d", &x, &y) != 2) {
  538.         put_msg(Err_incomp, "spline", line_no);
  539.         p->next = NULL;
  540.         free_splinestorage(s);
  541.         return(NULL);
  542.         };
  543.         if (x == 9999) break;
  544.         if (NULL == (Point_malloc(q))) {
  545.         put_msg(Err_mem);
  546.         free_splinestorage(s);
  547.         return(NULL);
  548.         }
  549.         q->x = x;
  550.         q->y = y;
  551.         p->next = q;
  552.         p = q;
  553.         c++;
  554.         }
  555.     p->next = NULL;
  556.     skip_line(fp);
  557.  
  558.     if (normal_spline(s)) return(s);
  559.  
  560.     skip_comment(fp);
  561.     /* Read controls */
  562.     if ((n = fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry)) != 4) {
  563.         put_msg(Err_incomp, "spline", line_no);
  564.         free_splinestorage(s);
  565.         return(NULL);
  566.         };
  567.     if (NULL == (s->controls = Control_malloc(cp))) {
  568.         put_msg(Err_mem);
  569.         free_splinestorage(s);
  570.         return(NULL);
  571.         }
  572.     cp->lx = lx; cp->ly = ly;
  573.     cp->rx = rx; cp->ry = ry;
  574.     while (--c) {
  575.         if (fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry) != 4) {
  576.         put_msg(Err_incomp, "spline", line_no);
  577.         cp->next = NULL;
  578.         free_splinestorage(s);
  579.         return(NULL);
  580.         };
  581.         if (NULL == (Control_malloc(cq))) {
  582.         put_msg(Err_mem);
  583.         cp->next = NULL;
  584.         free_splinestorage(s);
  585.         return(NULL);
  586.         }
  587.         cq->lx = lx; cq->ly = ly;
  588.         cq->rx = rx; cq->ry = ry;
  589.         cp->next = cq;
  590.         cp = cq;
  591.         }
  592.     cp->next = NULL;
  593.  
  594.     skip_line(fp);
  595.     return(s);
  596.     }
  597.  
  598. int
  599. scan_for_text(int spaces,char *src,char *dst)
  600. {
  601.     int spaces_found = 0;
  602.  
  603.     while(*src)
  604.     {
  605.         if(*src++ == ' ')
  606.         {
  607.             spaces_found++;
  608.  
  609.             if(spaces_found == spaces)
  610.                 break;
  611.         }
  612.     }
  613.  
  614.     if(*src == 0 || *src == '\n')
  615.         return(FALSE);
  616.  
  617.     while(*src)
  618.     {
  619.         if((*dst = *src++) == 1)
  620.         {
  621.             *dst = 0;
  622.             break;
  623.         }
  624.  
  625.         dst++;
  626.     }
  627.  
  628.     return(TRUE);
  629. }
  630.  
  631. static F_text *
  632. read_textobject()
  633. {
  634.     F_text    *t;
  635.     int    n, pen;
  636.     char    s[BUF_SIZE];
  637.  
  638.     Text_malloc(t);
  639.     t->next = NULL;
  640. /*    n = sscanf(buf,"%*d%d%d%d%d%d%d%f%d%d%d%d%d %[^\1]",*/
  641.     n = sscanf(buf,"%*d%d%d%d%d%d%d%f%d%d%d%d%d",
  642.         &t->font, &t->type, &t->size, &pen,
  643.         &t->color, &t->depth, &t->angle,
  644.         &t->style, &t->height, &t->length,
  645.         &t->base_x, &t->base_y);
  646.  
  647.     if (n != 13) {
  648.         put_msg(Err_incomp, "text", line_no);
  649.         free((char*)t);
  650.         return(NULL);
  651.         }
  652.  
  653.     if(!scan_for_text(13,buf,s))
  654.     {
  655.         put_msg(Err_incomp, "text", line_no);
  656.         free((char*)t);
  657.         return(NULL);
  658.     }
  659.  
  660.     t->cstring = (char*)malloc((unsigned)(strlen(s)+1));
  661.     if (NULL == t->cstring) {
  662.         put_msg(Err_mem);
  663.         free((char*)t);
  664.         return(NULL);
  665.         }
  666.     strcpy(t->cstring, s);
  667.     return(t);
  668.     }
  669.  
  670. get_line(fp)
  671. FILE    *fp;
  672. {
  673.     while (1) {
  674.         if (NULL == fgets(buf, BUF_SIZE, fp)) {
  675.         return(-1);
  676.         }
  677.         line_no++;
  678.         if (*buf != '#') return(1);        /* Skip comment lines */
  679.         }
  680.     }
  681.  
  682. skip_comment(fp)
  683. FILE    *fp;
  684. {
  685.     char c;
  686.  
  687.     while ((c = fgetc(fp)) == '#') skip_line(fp);
  688.     if (c != '#') ungetc(c, fp);
  689.     }
  690.  
  691. skip_line(fp)
  692. FILE    *fp;
  693. {
  694.     while (fgetc(fp) != '\n') {
  695.         if (feof(fp)) return;
  696.         }
  697.     }
  698.